/**
 * @file       IPEditField.cpp
 * @brief      TODO
 * @author     Huabo Zheng
 * @date       Jan 12, 2012
 * @Copyright  2012, www.netgear.com Inc. All rights reserved.
 */

#include "IPEditField.h"
#include "DigitChar.h"
#include <cstdio>
#include "errorcode.h"
#include <iosfwd>
#include <sstream>
#include <arpa/inet.h>

namespace NS_LCD_AFW
{

CIPEditField::CIPEditField()
{
	this->setFocusable(true);
	this->setHightlightable(true);
}

CIPEditField::~CIPEditField()
{
}

int CIPEditField::setText(std::string text)
{
	if (!isValidIpAddress(text))
	{
		return ERR_INVALID_IP_ADDRESS;
	}
	text = formatIpAddress(text);

	this->release();
	CChar *pTmp = NULL;
	std::ostringstream strName;
	for (std::size_t i = 0; i < text.length(); ++i)
	{
		OBJ_NEW(CDigitChar, pTmp);
		if (NULL == pTmp)
		{
			return ERR_NO_MEMORY;
		}
		strName << "CDigitChar" << i;
		CRect rect(getRect().getLeft() + i, getRect().getTop(), 1, 1);
		int iRet = pTmp->create(strName.str(), rect, this);
		if (ERR_SUCCESS != iRet)
		{
			pTmp->destory();
			pTmp = NULL;
			return iRet;
		}
		pTmp->setChar(text[i]);
		this->addChar(pTmp);
	}
	return ERR_SUCCESS;
}

int CIPEditField::setIP(unsigned char filed1, unsigned char filed2,
		unsigned char filed3, unsigned char filed4)
{
	std::string ipStr = uChar2Str(filed1) + "." + uChar2Str(filed2) + "."
			+ uChar2Str(filed3) + "." + uChar2Str(filed4);

	return setText(ipStr);
}

std::string CIPEditField::getIP() const
{
	return this->getText();
}

int CIPEditField::onCreate()
{
	CRect rect = getRect();
	rect.setWidth(IP_ADDRESS_WIDTH);
	rect.setHight(IP_ADDRESS_HEIGHT);
	setRect(rect);
	return CEditField::onCreate();
}

int CIPEditField::setIP(const std::string &ipAddr)
{
	return setText(ipAddr);
}

std::string CIPEditField::uChar2Str(unsigned char c)
{
	char tmp[4] =
	{ 0 };
	snprintf(tmp, sizeof(tmp), "%03u", c);
	return std::string(tmp);
}

bool CIPEditField::isValidIpAddress(const std::string & ipAddr)
{
	struct in_addr addr;
	int iRet = inet_aton(ipAddr.c_str(), &addr);
	return (iRet != 0);
}

std::string CIPEditField::formatIpAddress(const std::string & ipAddr)
{
	std::ostringstream ostr;
	unsigned char buf[sizeof(in_addr)] =
	{ 0 };
	if (0 != inet_aton(ipAddr.c_str(), (in_addr *) buf))
	{
		ostr << CIPEditField::uChar2Str(buf[0]) << "."
				<< CIPEditField::uChar2Str(buf[1]) << "."
				<< CIPEditField::uChar2Str(buf[2]) << "."
				<< CIPEditField::uChar2Str(buf[3]);
	}
	else
	{
		ostr << "000.000.000.000";
	}

	return ostr.str();
}

} /* namespace NS_LCD_AFW */
